#include "resource.h" 
#include "TestProj.h"
const char gszClassName[] = "myWindowClass";

enum LoadType {LoadF, LoadG, LoadDistance};

Tree* F=NULL;
Tree* G=NULL;
Distance* distanceFunc=NULL;
string resultsFileName = "";


void RunTest(HWND hwnd, int amount)//Run a test according to user parameters
{
	if(resultsFileName != "")//no results file name
	{
		bool DMRW = false,
		Klien = false,
		Shasha_Zhang = false,
		loadTest = false;//load or create a test?
		//check which algorithms are checked for testing
		if(IsDlgButtonChecked(hwnd , IDC_CHECK_DMRW) == BST_CHECKED)
			DMRW = true;
		if(IsDlgButtonChecked(hwnd , IDC_CHECK_KLIEN) == BST_CHECKED)
			Klien = true;
		if(IsDlgButtonChecked(hwnd , IDC_CHECK_SHASHA_ZHANG) == BST_CHECKED)
			Shasha_Zhang = true;
		if(IsDlgButtonChecked(hwnd , IDC_CHECK_LOAD) == BST_CHECKED)
			loadTest = true;
		//run the test
		TestProj test(resultsFileName , DMRW , Klien , Shasha_Zhang);
		if(loadTest)
			test.TestProjLoad(amount, distanceFunc);
		else
			test.TestProjCreate(amount, distanceFunc);
	}
}


void ShowAbout(HWND hwnd)
{
	MessageBox(hwnd, "Created by Boris Pismenny for the University of Haifa.", "About", MB_OK);
}

void CalcTED(HWND hwnd)//Calculates TED according to the parameters entered by the user
{
	if(F != NULL && G != NULL)//Do we have 2 trees?
	{
		Algorithm alg;//algorithm chosen by the user defined at TED.h
		BOOL checked;
		checked = IsDlgButtonChecked(hwnd , IDC_RADIO_DMRW);
		if(checked)
			alg = OPT;
		else
		{
			checked = IsDlgButtonChecked(hwnd , IDC_RADIO_KLIEN);
			if(checked)
				alg = KLIEN;
			else
			{
				checked = IsDlgButtonChecked(hwnd , IDC_RADIO_SHASHA_ZHANG);
				if(checked)
					alg = SHASHA_ZHANG;
				else
				{
					MessageBox(hwnd, "No Algorithm specified" , "Error", MB_ICONERROR);
					return;
				}
			}
		}
		TED ted(F, G, distanceFunc,alg);//Run TED for the trees , algorithm and distance metric specified
		string result;
		result = ItoS(ted.GetTED());
		MessageBox(hwnd, result.c_str() , "Result", MB_OK);
	}
	else
	{
		MessageBox(hwnd , "Please enter 2 trees" , "Error", MB_ICONERROR);
	}
}

void LoadFile(string szFileName, LoadType type)//loads a file chosen by the user in function DoFileOpen
											   //according to the prameter Tree or Distance metric
{
	if(type == LoadF)
	{
		if(F != NULL)
			F->~Tree();
		F = Load(szFileName);
	}
	if(type == LoadG)
	{
		if(G != NULL)
			G->~Tree();
		G = Load(szFileName);
	}
	if(type == LoadDistance)
	{
		if(distanceFunc == NULL)
			distanceFunc = new Distance();
		if(!distanceFunc->IsEmpty())
			distanceFunc->Clear();
		distanceFunc->Load(szFileName);
	}
}

void DoFileSave(HWND hwnd)//Saves a file in a directory chosen by the user
{
	OPENFILENAME ofn;
	char szFileName[MAX_PATH] = "";

	ZeroMemory(&ofn, sizeof(ofn));

	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = hwnd;
	ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
	ofn.lpstrFile = szFileName;
	ofn.nMaxFile = MAX_PATH;
	ofn.lpstrDefExt = "txt";
	ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;

	if(GetSaveFileName(&ofn))
	{
		resultsFileName = szFileName;
	}
}

void DoFileOpen(HWND hwnd, LoadType type)//Opens a file from a directory chosen by the user
{
	OPENFILENAME ofn;
	char szFileName[MAX_PATH] = "";

	ZeroMemory(&ofn, sizeof(ofn));

	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = hwnd;
	ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
	ofn.lpstrFile = szFileName;
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
	ofn.lpstrDefExt = "txt";

	if(GetOpenFileName(&ofn))
	{
		LoadFile(szFileName, type);
	}
}

BOOL CALLBACK TestDlg(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message)
	{
		case WM_CLOSE:
			EndDialog(hwnd, 0);
		break;
		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
				case ID_RUN://pressed the Run Test button
				{
					int amount;//recieves the information from the text box
					amount =  GetDlgItemInt(hwnd , IDC_EDIT , NULL , NULL);
					RunTest(hwnd , amount);//runs the test
					EndDialog(hwnd, 1);
				}
				break;
				case ID_BUTTON_SAVE_RESULTS://save the resutls
					DoFileSave(hwnd);
				break; 
			}
		break;
		default:
			return FALSE;
	}
	return TRUE;
}


BOOL CALLBACK RunDlg(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message)
	{
		case WM_CLOSE:
			EndDialog(hwnd, 0);
		break;
		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
				case IDC_BUTTON_LOADF: //pressed the Load F tree button
					DoFileOpen(hwnd, LoadF);
				break;
				case IDC_BUTTON_LOADG: //pressed the Load G tree button
					DoFileOpen(hwnd, LoadG);
				break;
				case IDC_BUTTON_LOAD_DISTANCE: //pressed the Load Distance button
					DoFileOpen(hwnd, LoadDistance);
				break;
				case IDC_BUTTON_CALC: //pressed the Claculate Tree Edit Distance button
					CalcTED(hwnd);
				break;
			}
		break;
		default:
			return FALSE;
	}
	return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) //handles the main window
{
	switch(Message)
	{
		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
				case ID_OPERATION_RUN://pressed the run button
				{
					DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_RUN_TED), NULL, RunDlg);
				}
				break;
				case ID_OPERATION_TEST://pressed the test button
				{
					DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_TEST), NULL, TestDlg);
				}
				break;
				case ID_HELP_ABOUT://pressed the about button
					ShowAbout(hwnd);
				break;
			}
		break;
		case WM_CLOSE:
			DestroyWindow(hwnd);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			   return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX WndClass;
	HWND hwnd;
	MSG Msg;


	WndClass.cbSize        = sizeof(WNDCLASSEX);
	WndClass.style         = NULL;
	WndClass.lpfnWndProc   = WndProc;
	WndClass.cbClsExtra    = 0;
	WndClass.cbWndExtra    = 0;
	WndClass.hInstance     = hInstance;
	WndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
	WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	WndClass.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU);
	WndClass.lpszClassName = gszClassName;
	WndClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

	if(!RegisterClassEx(&WndClass)) 
	{
		MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK);
		return 0;
	}

	hwnd = CreateWindowEx(
		   WS_EX_STATICEDGE,
		   gszClassName,
		   "Tree Edit Distance Menu",
		   WS_OVERLAPPEDWINDOW,
		   CW_USEDEFAULT, CW_USEDEFAULT,
		   240, 120,
		   NULL, NULL,
		   hInstance,
		   NULL);

	if(hwnd == NULL) {
		   MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK);
		   return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	while(GetMessage(&Msg, NULL, 0, 0)) {
		   TranslateMessage(&Msg);
		   DispatchMessage(&Msg);
	}
	return Msg.wParam;
}

